﻿/*
 * Copyright (C) 2011 The Calculator for Android Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.japminh.tool.calculator.gui;

import net.japminh.tool.calculator.Const;
import net.japminh.tool.calculator.R;
import net.japminh.tool.calculator.model.CalculateType;
import net.japminh.tool.calculator.util.DoubleUtils;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

/**
 * メインActivity
 * @author thangns
 *
 */
public class MainActivity extends Activity implements OnClickListener, OnLongClickListener {

	private double value1 = Const.DEFAULT_DOUBLE_VALUE, value2 = Const.DEFAULT_DOUBLE_VALUE;

	private CalculateType calculateType;

	private TextView result;

	private boolean inputNumber = Const.DEFAULT_BOOLEAN_VALUE;

	private AlertDialog infoDialog;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView();
	}

	private void setContentView() {
		setContentView(R.layout.main);

		result = (TextView) findViewById(R.id.txtResult);

		// +/-の切り替え
		findViewById(R.id.btnPlusMinus).setOnClickListener(this);

		// 演算入力
		findViewById(R.id.btnDivide).setOnClickListener(this);
		findViewById(R.id.btnMultiply).setOnClickListener(this);
		findViewById(R.id.btnMinus).setOnClickListener(this);
		findViewById(R.id.btnPlus).setOnClickListener(this);

		// 数字入力
		findViewById(R.id.btnDot).setOnClickListener(this);
		findViewById(R.id.btnNum0).setOnClickListener(this);
		findViewById(R.id.btnNum00).setOnClickListener(this);
		findViewById(R.id.btnNum1).setOnClickListener(this);
		findViewById(R.id.btnNum2).setOnClickListener(this);
		findViewById(R.id.btnNum3).setOnClickListener(this);
		findViewById(R.id.btnNum4).setOnClickListener(this);
		findViewById(R.id.btnNum5).setOnClickListener(this);
		findViewById(R.id.btnNum6).setOnClickListener(this);
		findViewById(R.id.btnNum7).setOnClickListener(this);
		findViewById(R.id.btnNum8).setOnClickListener(this);
		findViewById(R.id.btnNum9).setOnClickListener(this);

		findViewById(R.id.btnEquals).setOnClickListener(this);
		findViewById(R.id.btnAC).setOnClickListener(this);
		findViewById(R.id.btnDel).setOnClickListener(this);

		findViewById(R.id.btnDel).setOnLongClickListener(this);
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		if (calculateType == null) {
			outState.putInt("calculateTypeValue", -1);
		} else {
			outState.putInt("calculateTypeValue", calculateType.ordinal());
		}
		outState.putDouble("value1", value1);
		outState.putDouble("value2", value2);
		outState.putBoolean("inputNumber", inputNumber);
		outState.putCharSequence("resultValue", result.getText());
	}

	@Override
	protected void onRestoreInstanceState(Bundle savedInstanceState) {
		super.onRestoreInstanceState(savedInstanceState);

		int calculateTypeValue = savedInstanceState.getInt("calculateTypeValue", -1);
		if (calculateTypeValue < 0) {
			calculateType = null;
		} else {
			calculateType = CalculateType.values()[calculateTypeValue];
		}
		value1 = savedInstanceState.getDouble("value1", Const.DEFAULT_DOUBLE_VALUE);
		value2 = savedInstanceState.getDouble("value2", Const.DEFAULT_DOUBLE_VALUE);
		inputNumber = savedInstanceState.getBoolean("inputNumber", Const.DEFAULT_BOOLEAN_VALUE);
		result.setText(savedInstanceState.getCharSequence("resultValue"));
	}

	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);

		CharSequence resultValue = result.getText();
		setContentView();
		result.setText(resultValue);
	}

	@Override
	public void onClick(View v) {
		String str = result.getText().toString();

		switch (v.getId()) {
		case R.id.btnPlusMinus:
			if (str.length() > 0) {
				if (str.charAt(0) == '-') {
					result.setText(str.substring(1));
				} else {
					result.setText('-' + str);
				}
			}
			break;

		case R.id.btnAC:
			allClear();
			break;

		case R.id.btnDel:
			if (inputNumber && (str.length() > 1)) {
				result.setText(str.substring(0, str.length() - 1));
			} else {
				result.setText("0");
			}
			break;

		case R.id.btnEquals:
			if (calculateType != null) {
				value2 = Double.valueOf(str);

				double res = DoubleUtils.calculation(value1, value2, calculateType);
				String resStr = DoubleUtils.round(res);
				if (resStr == null) {
					Toast.makeText(this, R.string.error_too_big, Toast.LENGTH_SHORT).show();
					resStr = "0";
				} else {
					result.setText(resStr);
				}
			}
			inputNumber = false;
			break;

		case R.id.btnDot:
			if (inputNumber) {
				if (str.indexOf('.') < 0) {
					result.setText(str + ".");
				}
			} else {
				result.setText("0.");
			}
			inputNumber = true;
			break;

		case R.id.btnNum0:
		case R.id.btnNum00:
		case R.id.btnNum1:
		case R.id.btnNum2:
		case R.id.btnNum3:
		case R.id.btnNum4:
		case R.id.btnNum5:
		case R.id.btnNum6:
		case R.id.btnNum7:
		case R.id.btnNum8:
		case R.id.btnNum9:
			String label = ((Button) (v)).getText().toString();
			if (inputNumber && (str.length() + label.length() > Const.INPUT_MAX_LENGTH)) {
				return;
			}

			if ((!inputNumber) || "0".equals(str)) {
				if (v.getId() == R.id.btnNum00) {
					str = "0";
				} else {
					str = label;
				}
			} else {
				str += label;
			}

			result.setText(str);
			inputNumber = true;
			break;

		case R.id.btnDivide:
			setValues(CalculateType.Divide, Double.valueOf(str), false);
			break;

		case R.id.btnMinus:
			setValues(CalculateType.Minus, Double.valueOf(str), false);
			break;

		case R.id.btnMultiply:
			setValues(CalculateType.Multiply, Double.valueOf(str), false);
			break;

		case R.id.btnPlus:
			setValues(CalculateType.Plus, Double.valueOf(str), false);
			break;
		}
	}

	private void allClear() {
		value1 = value2 = 0.0;
		inputNumber = true;
		calculateType = null;
		result.setText("0");
	}

	private void setValues(CalculateType calculateType, double value1, boolean inputNumber) {
		this.calculateType = calculateType;
		this.value1 = value1;
		this.inputNumber = inputNumber;
	}

	@Override
	public boolean onLongClick(View v) {
		switch (v.getId()) {
		case R.id.btnDel:
			result.setText("0");
			return true;
		}
		return false;
	}

	/**
	 * 「アプリについて」のアラートを生成する
	 *
	 * @return
	 */
	protected AlertDialog createInfoDialog() {
		LayoutInflater inflater = LayoutInflater.from(this);
		final View aboutAppView = inflater.inflate(R.layout.about_app, null);
		AlertDialog.Builder ad = new AlertDialog.Builder(this);
		ad.setIcon(android.R.drawable.ic_dialog_info);
		ad.setTitle(R.string.screen_title_info);
		ad.setView(aboutAppView);
		ad.setNeutralButton(R.string.label_close, new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
			}
		});
		return ad.create();
	}

	/*
	 * (非 Javadoc)
	 *
	 * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
	 */
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.base, menu);
		return true;
	}

	/*
	 * (非 Javadoc)
	 *
	 * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
	 */
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.menu_info:
			// アプリについて
			if (infoDialog == null) {
				infoDialog = createInfoDialog();
			}
			if (!infoDialog.isShowing()) {
				infoDialog.show();
			}
			return true;
		}
		return super.onOptionsItemSelected(item);
	}
}
